# -*- coding: utf-8 -*-
"""
Created on Tue Jul  2 10:59:04 2024

@author: LBW sstc 20240702
    边界条件更新
"""
# private pkgs
from utils.constant import BoundaryConditionType
from algorithm.physical_property.tab_loader import TabLoader
from utils.constant import BoundaryConditionType

def find_time_interval(time_list: list, time_point: float) -> int:
    """
    找到time_point在time_list中的区间, 并确定它刚好大于哪个值;
    入口边界可控时, 时间点在时间列表中, 返回index;
    入口边界不可控时, 返回-1;
    时间点小于时间列表中的所有时间点, 返回0;
    时间点大于时间列表中的所有时间点, 返回-1;

    参数:
    - time_list: 已排序的时间列表
    - time_point: 需要查找的时间点

    返回:
    - 刚好大于时间点的index
    """
    # 确保时间列表是有序的
    time_list.sort()

    # 找到时间点所在的区间
    for i in range(len(time_list) - 1):
        if time_list[i] <= time_point < time_list[i + 1]:
            return i

    # 如果时间点大于列表中的所有时间点
    if time_point >= time_list[-1]:
        return -1

    # 如果时间点小于列表中的所有时间点
    if time_point < time_list[0]:
        return 0

def update_boundary(params: dict, inlet_Rs_g: float) -> dict:
    """ 每个迭代步更新边界条件
        1.一般需要更新的边界变量有
        - 入口边界: 温度, 压力, 速度, 密度, 截面分数
        - 出口边界: 压力, 温度, 速度, 密度, 截面分数
        2.水龙头不考虑温度
        
    Args:
        params: dict;计算需要的输入参数 
        inlet_Rs_g: float; 入口气体质量分数
    Returns:
        params: dict; 更新边界条件后的的输入参数

    """
    cross_section_area_segment = params["cross_section_area_segment"]
    
    # if params["boundary_class"] == BoundaryConditionType.inlet_M_outlet_p.value:
    # 检查计算模拟时间步是否在边界变化节点
    try:
        index = find_time_interval(params["inlet_M_time"], params["record_time"])
        inlet_M = params["inlet_M_value"][index]
    except:
        inlet_M = params["inlet_M_value"][0]

    try:
        index = find_time_interval(params["inlet_T_time"], params["record_time"])
        inlet_T = params["inlet_T_value"][index]
    except:
        inlet_T = params["inlet_T_value"][0]

    try:
        index = find_time_interval(params["outlet_p_time"], params["record_time"])
        outlet_p = params["outlet_p_value"][index]
    except:
        outlet_p = params["outlet_p_value"][0]

    # inlet update
    params["rho_g_node"][0] = params["rho_g_node"][1]
    params["rho_L_node"][0] = params["rho_L_node"][1]

    params["alpha_g_node"][0] = params["alpha_g_node"][1]
    params["alpha_L_node"][0] = params["alpha_L_node"][1]

    params["V_g_segment"][0] = (
        inlet_M
        * inlet_Rs_g
        / params["rho_g_node"][0]
        / params["alpha_g_node"][0]
        / cross_section_area_segment[0]
    )
    params["V_L_segment"][0] = (
        inlet_M
        * (1 - inlet_Rs_g)
        / params["rho_L_node"][0]
        / params["alpha_L_node"][0]
        / cross_section_area_segment[0]
    )

    params["p_node"][0] = params["p_node"][1]
    params["T_node"][0] = inlet_T

    # outlet update (open boundary)
    params["p_node"][-1] = outlet_p
    params["T_node"][-1] = params["T_node"][-2]
    params["alpha_g_node"][-1] = params["alpha_g_node"][-2]
    params["alpha_L_node"][-1] = params["alpha_L_node"][-2]
    params["alpha_D_node"][-1] = params["alpha_D_node"][-2]
    params["rho_g_node"][-1] = params["rho_g_node"][-2]
    params["rho_L_node"][-1] = params["rho_L_node"][-2]
    params["V_g_segment"][-1] = params["V_g_segment"][-2]
    params["V_L_segment"][-1] = params["V_L_segment"][-2]
    params["V_D_segment"][-1] = params["V_D_segment"][-2]

    # elif params["boundary_class"] == BoundaryConditionType.inlet_p_outlet_M.value:
    #     try:
    #         index = find_time_interval(params["inlet_p_time"], params["record_time"])
    #         inlet_p = params["inlet_p_value"][index]
    #     except:
    #         inlet_p = params["inlet_p_value"][0]
        
    #     try:
    #         index = find_time_interval(params["outlet_M_time"], params["record_time"])
    #         outlet_M = params["outlet_M_value"][index]
    #     except:
    #         outlet_M = params["outlet_M_value"][0]
        
    #     try:
    #         index = find_time_interval(params["outlet_T_time"], params["record_time"])
    #         outlet_T = params["outlet_T_value"][index]
    #     except:
    #         outlet_T = params["outlet_T_value"][0]
        
    #     # 获取物性
    #     tab_dict = rt.get_physical_properties_data(params["p_node"][-2], outlet_T) # open boundary, 用倒数第二个点代替最后一个点
    #     try:
    #         outlet_rho_L = tab_dict["oil_density"][0]
    #         outlet_rho_g = tab_dict["gas_density"][0]
    #         outlet_Rs_g = tab_dict["gas_mass_fraction"][0]
    #     except:
    #         outlet_rho_L = tab_dict['liquid_density']
    #         outlet_rho_g = tab_dict['gas_density']
    #         outlet_Rs_g = tab_dict['gas_mass_fraction']
        
    #     # inlet 
    #     params["p_node"][0] = inlet_p
    #     params["T_node"][0] = params["T_node"][1]
        
    #     params["rho_g_node"][0] = params["rho_g_node"][1]
    #     params["rho_L_node"][0] = params["rho_L_node"][1]
        
    #     params["alpha_g_node"][0] = params["alpha_g_node"][1]
    #     params["alpha_L_node"][0] = 1 - params["alpha_g_node"][0]
        
    #     params["V_g_segment"][0] = params["V_g_segment"][1]
    #     params["V_L_segment"][0] = params["V_L_segment"][1]

    #     # outlet (open boundary)
    #     params["p_node"][-1] = params["p_node"][-2]
    #     params["T_node"][-1] = outlet_T
        
    #     params["rho_g_node"][-1] = outlet_rho_g
    #     params["rho_L_node"][-1] = outlet_rho_L
    #     params["alpha_g_node"][-1] = params["alpha_g_node"][-2]
    #     params["alpha_L_node"][-1] = 1 - params["alpha_g_node"][-1]
        
    #     params["V_g_segment"][-1] = (
    #         outlet_M
    #         * outlet_Rs_g
    #         / outlet_rho_g
    #         / params["alpha_g_node"][-1]
    #         / cross_section_area_segment
    #     )
    #     params["V_L_segment"][-1] = (
    #         outlet_M
    #         * (1 - outlet_Rs_g)
    #         / outlet_rho_L
    #         / params["alpha_L_node"][-1]
    #         / cross_section_area_segment
    #     )
        
    # elif params["boundary_class"] == BoundaryConditionType.inlet_p_outlet_p.value:
    #     try:
    #         index = find_time_interval(params["inlet_p_time"], params["record_time"])
    #         inlet_p = params["inlet_p_value"][index]
    #     except:
    #         inlet_p = params["inlet_p_value"][0]
        
    #     try:
    #         index = find_time_interval(params["outlet_p_time"], params["record_time"])
    #         outlet_p = params["outlet_p_value"][index]
    #     except:
    #         outlet_p = params["outlet_p_value"][0]
        
    #     try:
    #         index = find_time_interval(params["outlet_T_time"], params["record_time"])
    #         outlet_T = params["outlet_T_value"][index]
    #     except:
    #         outlet_T = params["outlet_T_value"][0]
        
    #     # 获取物性
    #     tab_dict_inlet = rt.get_physical_properties_data(inlet_p, params["T_node"][1]) # open boundary, 用倒数第二个点代替最后一个点
    #     try:
    #         inlet_rho_L = tab_dict_inlet["oil_density"][0]
    #         inlet_rho_g = tab_dict_inlet["gas_density"][0]
    #         inlet_Rs_g = tab_dict_inlet["gas_mass_fraction"][0]
    #     except:
    #         inlet_rho_L = tab_dict_inlet['liquid_density']
    #         inlet_rho_g = tab_dict_inlet['gas_density']
    #         inlet_Rs_g = tab_dict_inlet['gas_mass_fraction']
            
    #     tab_dict_outlet = rt.get_physical_properties_data(outlet_p, outlet_T)
    #     try:
    #         outlet_rho_L = tab_dict_outlet["oil_density"][0]
    #         outlet_rho_g = tab_dict_outlet["gas_density"][0]
    #         outlet_Rs_g = tab_dict_outlet["gas_mass_fraction"][0]
    #     except:
    #         outlet_rho_L = tab_dict_outlet['liquid_density']
    #         outlet_rho_g = tab_dict_outlet['gas_density']
    #         outlet_Rs_g = tab_dict_outlet['gas_mass_fraction']

    #     # inlet
    #     params["p_node"][0] = inlet_p
    #     params["T_node"][0] = params["T_node"][1]
        
    #     params["rho_g_node"][0] = inlet_rho_g
    #     params["rho_L_node"][0] = inlet_rho_L
        
    #     params["alpha_g_node"][0] = params["alpha_g_node"][1]
    #     params["alpha_L_node"][0] = 1 - params["alpha_g_node"][0]
        
    #     params["V_g_segment"][0] = params["V_g_segment"][1]
    #     params["V_L_segment"][0] = (1/inlet_Rs_g - 1)*params["rho_g_node"][0]*params["V_g_segment"][0]*params["alpha_g_node"][0]/(params["alpha_L_node"][0]*inlet_rho_L)
        
    #     # outlet
    #     params["p_node"][-1] = outlet_p
    #     params["T_node"][-1] = outlet_T
        
    #     params["rho_g_node"][-1] = outlet_rho_g
    #     params["rho_L_node"][-1] = outlet_rho_L
        
    #     params["alpha_g_node"][-1] = params["alpha_g_node"][-2]
    #     params["alpha_L_node"][-1] = 1 - params["alpha_g_node"][-1]
        
    #     params["V_g_segment"][-1] = (1/outlet_Rs_g - 1)*params["rho_L_node"][-1]*params["V_L_segment"][-1]*params["alpha_L_node"][-1]/(params["alpha_g_node"][-1]*outlet_rho_g)
    #     params["V_L_segment"][-1] = params["V_L_segment"][-2]